package cloud.dandanit.itservice.controller.article;

import cloud.dandanit.itservice.entity.Article;
import cloud.dandanit.itservice.entity.ArticleClasses;
import cloud.dandanit.itservice.entity.excel.ExcelSubjectData;
import cloud.dandanit.itservice.entity.vo.ArticleVo;
import cloud.dandanit.itservice.entity.vo.OneSubject;
import cloud.dandanit.itservice.entity.vo.TwoSubject;
import cloud.dandanit.itservice.listener.ExcelSubjectListener;
import cloud.dandanit.itservice.service.ArticleClassesService;
import cloud.dandanit.itservice.service.ArticleService;
import cloud.dandanit.itservice.utils.R;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程简介 前端控制器
 * </p>
 *
 * @author luokai
 * @since 2022-07-05
 */
@SuppressWarnings({"DuplicatedCode", "AlibabaUndefineMagicConstant"})
@RestController
@RequestMapping("/itservice/articleadmin")
public class ArticleAdminController {

    @Autowired
    private ArticleService articleService;

    @Autowired
    private ArticleClassesService articleClassesService;


    @ApiOperation(value = "获取文章分页列表")
    @GetMapping("pageArticle/{page}/{limit}")
    public R getPageArticle(
            @ApiParam(name = "page", value = "当前页码", required = true)
            @PathVariable Long page,
            @ApiParam(name = "limit", value = "每页记录数", required = true)
            @PathVariable Long limit) {

        Page<Article> pageParam = new Page<>(page, limit);
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id","title","summary","cls_id", "cls_parent_id","sort","difficulty","state","view_num","gmt_create","gmt_modified");
        queryWrapper.orderByDesc("gmt_modified");
        articleService.page(pageParam,queryWrapper);
        return R.ok().data("items", pageParam.getRecords()).data("total", pageParam.getTotal());
    }

    @ApiOperation(value = "获取文章分页列表+一二级分类")
    @GetMapping("pageArticleAndClasses/{page}/{limit}")
    public R getPageArticleAndClasses(
            @ApiParam(name = "page", value = "当前页码", required = true)
            @PathVariable Long page,
            @ApiParam(name = "limit", value = "每页记录数", required = true)
            @PathVariable Long limit) {

        Page<Article> pageArticle = new Page<>(page, limit);
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id","title","summary","cls_id", "cls_parent_id","sort","difficulty","state","view_num","gmt_create","gmt_modified");
        queryWrapper.orderByDesc("gmt_modified");
        articleService.page(pageArticle,queryWrapper);

        Page<ArticleVo> pageArticleVo = new Page<>(page, limit);

        BeanUtils.copyProperties(pageArticle, pageArticleVo, "records");

        List<Article> records = pageArticle.getRecords();

        List<ArticleVo> articleVoList = records.stream().map((item) -> {
            ArticleVo articleVo = new ArticleVo();
            //将dishDto除了categoryName属性外的属性通过item拷贝过来
            BeanUtils.copyProperties(item, articleVo);

            //获取item属性的categoryId
            String clsParentId = item.getClsParentId();
            String clsId = item.getClsId();

            String clsParentTitle = articleClassesService.getById(clsParentId).getTitle();
            articleVo.setClsParentTitle(clsParentTitle);

            String clsTitle = articleClassesService.getById(clsId).getTitle();
            articleVo.setClsTitle(clsTitle);

            return articleVo;
        }).collect(Collectors.toList());

        pageArticleVo.setRecords(articleVoList);

        return R.ok().data("items", pageArticleVo.getRecords()).data("total", pageArticleVo.getTotal());
    }

    @ApiOperation(value = "新增文章")
    @PostMapping("addArticle")
    public R save(
            @ApiParam(name = "article", value = "文章实体", required = true)
            @RequestBody Article article) {

        articleService.save(article);
        return R.ok();
    }

    @ApiOperation(value = "根据id获取文章")
    @GetMapping("getArticleById/{id}")
    public R getArticleById(
            @ApiParam(name = "id", value = "文章ID", required = true)
            @PathVariable String id) {

        Article article = articleService.getById(id);
        return R.ok().data("article", article);
    }

    @ApiOperation(value = "修改文章")
    @PostMapping("update")
    public R update(
            @ApiParam(name = "article", value = "文章实体", required = true)
            @RequestBody Article article) {

        articleService.updateById(article);
        return R.ok();
    }

    @ApiOperation(value = "删除文章")
    @DeleteMapping("removeArticleById/{id}")
    public R removeArticleById(
            @ApiParam(name = "id", value = "文章ID", required = true)
            @PathVariable String id) {

        articleService.removeById(id);
        return R.ok();
    }

    @ApiOperation(value = "搜索文章")
    @GetMapping("searchArticle/{keyword}")
    public R searchArticle(
            @ApiParam(name = "keyword", value = "关键字", required = true)
            @PathVariable String keyword) {

        //空搜索框搜索全部
        if ("null".equals(keyword)) {

            return R.ok().data("searchResult",articleService.list(null));
        }

        //查询title字段
        QueryWrapper<Article> queryWrapperTitle = new QueryWrapper<>();
        queryWrapperTitle.like("title", keyword)
                .select("id","title","summary","cls_id", "cls_parent_id","sort","state","difficulty","view_num","gmt_create","gmt_modified");
        List<Article> titleList = articleService.list(queryWrapperTitle);

        //查询summary字段
        QueryWrapper<Article> queryWrapperSummary = new QueryWrapper<>();
        queryWrapperSummary.like("summary", keyword)
                .select("id","title","summary","cls_id", "cls_parent_id","sort","state","difficulty","view_num","gmt_create","gmt_modified");
        List<Article> summaryList = articleService.list(queryWrapperSummary);
        //求并集
        titleList.addAll(summaryList);
        //集合去重
        List<Article> resultList = titleList.stream().distinct().collect(Collectors.toList());

        // 拷贝属性
        List<ArticleVo> articleVoList = resultList.stream().map((item) -> {
            ArticleVo articleVo = new ArticleVo();
            //将dishDto除了categoryName属性外的属性通过item拷贝过来
            BeanUtils.copyProperties(item, articleVo);

            //获取item属性的categoryId
            String clsParentId = item.getClsParentId();
            String clsId = item.getClsId();

            String clsParentTitle = articleClassesService.getById(clsParentId).getTitle();
            articleVo.setClsParentTitle(clsParentTitle);

            String clsTitle = articleClassesService.getById(clsId).getTitle();
            articleVo.setClsTitle(clsTitle);

            return articleVo;
        }).collect(Collectors.toList());

        return R.ok().data("searchResult",articleVoList);
    }

    @ApiOperation(value = "根据类别查看文章")
    @GetMapping("getArtilceListByClassesId/{articleClassesId}")
    public R getArtilceListByClassesId(
            @ApiParam(name = "articleClassesId", value = "二级分类id", required = true)
            @PathVariable String articleClassesId) {

        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        if (articleClassesId.length() > 14) {
            queryWrapper.eq("cls_id", articleClassesId);
        } else {
            queryWrapper.eq("difficulty", articleClassesId);
        }
        queryWrapper.select("id","title","summary","cls_id", "cls_parent_id","sort","difficulty","state","view_num","gmt_create","gmt_modified");
        queryWrapper.orderByDesc("gmt_modified");

        List<Article> articleList = articleService.list(queryWrapper);

        // 拷贝属性
        List<ArticleVo> articleVoList = articleList.stream().map((item) -> {
            ArticleVo articleVo = new ArticleVo();
            //将dishDto除了categoryName属性外的属性通过item拷贝过来
            BeanUtils.copyProperties(item, articleVo);

            //获取item属性的categoryId
            String clsParentId = item.getClsParentId();
            String clsId = item.getClsId();

            String clsParentTitle = articleClassesService.getById(clsParentId).getTitle();
            articleVo.setClsParentTitle(clsParentTitle);

            String clsTitle = articleClassesService.getById(clsId).getTitle();
            articleVo.setClsTitle(clsTitle);

            return articleVo;
        }).collect(Collectors.toList());

        return R.ok().data("classResult",articleVoList);
    }


    @ApiOperation(value = "批量删除文章")
    @DeleteMapping("batchDelete")
    public R batchDelete(
            @ApiParam(name = "ids", value = "文章ID集合", required = true)
            @RequestBody List<String> ids) {

        articleService.removeByIds(ids);
        return R.ok();
    }

    @ApiOperation(value = "更改文章状态")
    @GetMapping("changeState/{articleId}")
    public R changeState(
            @ApiParam(name = "articleId", value = "轮播图ID", required = true)
            @PathVariable String articleId) {

        Article article = articleService.getById(articleId);
        if (article.getState()==0) {
            article.setState(1);
        } else {
            article.setState(0);
        }
        articleService.updateById(article);

        return R.ok();
    }

    @ApiOperation(value = "一键修改文章状态")
    @GetMapping("batchChangeArticleState/{state}")
    public R batchChangeArticleState(
            @ApiParam(name = "state", value = "更改的状态", required = true)
            @PathVariable Integer state) {

        List<Article> articleList = articleService.list(null);
        for (Article article : articleList) {
            article.setState(state);
        }
        articleService.updateBatchById(articleList);
        return R.ok();
    }


    @ApiOperation(value = "查看文章一二级标题")
    @GetMapping("getAllArticleClasses")
    public R getAllArticleClasses() {

        //1 查询所有的一级分类 parent_id==0
        QueryWrapper<ArticleClasses> wrapperOne = new QueryWrapper<>();
        wrapperOne.eq("parent_id", "0");
        List<ArticleClasses> oneSubjectList = articleClassesService.list(wrapperOne);

        //2 查询所有的二级分类 parent_id!=0
        QueryWrapper<ArticleClasses> wrapperTwo = new QueryWrapper<>();
        wrapperTwo.ne("parent_id", "0");
        List<ArticleClasses> twoSubjectList = articleClassesService.list(wrapperTwo);

        //创建list集合存储最终封装的数据
        List<OneSubject> finalSubjectList = new ArrayList<>();

        //3 封装一级分类
        //拷贝List<EduSubject> -> List<OneSubject>
        for (ArticleClasses eduSubject : oneSubjectList) {
            OneSubject oneSubject = new OneSubject();
            BeanUtils.copyProperties(eduSubject, oneSubject);
            finalSubjectList.add(oneSubject);

            //4 封装二级分类
            //在一级分类中遍历查询所有的二级分类
            List<TwoSubject> towFinalSubjectList = new ArrayList<>();
            for (ArticleClasses tSubject : twoSubjectList) {
                //获取每个二级分类
                //判断二级分类parentid和一级分类id是否一样
                if (tSubject.getParentId().equals(eduSubject.getId())) {
                    //把twoSubject值复制到TwoSubject里面，放到towFinalSubjectList里
                    TwoSubject twoSubject = new TwoSubject();
                    BeanUtils.copyProperties(tSubject, twoSubject);
                    towFinalSubjectList.add(twoSubject);
                }
            }

            //把一级下面所有分类放到一级分类里面
            oneSubject.setChildren(towFinalSubjectList);
        }

        return R.ok().data("list", finalSubjectList);
    }


    //添加课程分类
    //获取上传过来文件，把文件内容读取过来
    @PostMapping("addClasses")
    @ApiOperation("添加分类")
    public R addSubject(
            @ApiParam(name = "file", value = "前端文件", required = true)
            MultipartFile file) {

        //上传过来的文件
        try {
            //文件输入流
            InputStream inputStream = file.getInputStream();
            EasyExcel.read(inputStream, ExcelSubjectData.class, new ExcelSubjectListener(articleClassesService)).sheet().doRead();

        } catch (Exception e){
            e.printStackTrace();
        }
        return R.ok();
    }

}

